// const parser = require("@babel/parser");
// const traverse = require("@babel/traverse").default;
// const code = `
//   function func() {
//     const guang = 'guang';
//     function func2() {
//       const ssh = 'ssh';
//       {
//         function func3 () {
//           const suzhe = 'suzhe';
//         }
//       }
//     }
//   }
// `;

// const ast = parser.parse(code);

// traverse(ast, {
//   FunctionDeclaration(path) {
//     if (path.get("id.name").node === "func3") {
//       traverse;
//       console.log(path.scope.dump());
//     }
//   },
// });

function func() {
  const guang = "guang";
  function func2() {
    const ssh = "ssh";
    function func3() {
      const suzhe = "suzhe";
      console.log("🚀 ～ file: 1.js:31 ～ func2 ～ ssh:", ssh);
      console.log("🚀 ～ file: 1.js:29 ～ func ～ guang:", guang);
    }
    return func3;
  }
  return func2;
}

const func2 = func();
const func3 = func2();
func3();

// 所以，闭包是 当一个函数  返回 函数 的时候  扫描函数内的标识符引用，  把用到的本作用域的变量打成 Closure 包，放到 [[Scopes]] 里。

// 闭包是在函数创建的时候，让函数打包带走的根据函数内的外部引用来过滤作用域链剩下的链。
// 它是在函数创建的时候生成的作用域链的子集，是打包的外部环境。evel 因为没法分析内容，所以直接调用会把整个作用域打包（所以尽量不要用 eval，容易在闭包保存过多的无用变量），而不直接调用则没有闭包。
// https://juejin.cn/post/6957913856488243237
